package cn.sciento.transfer.infra.rocketmq.vo;

import com.alibaba.fastjson.JSON;
import cn.sciento.core.exception.CommonException;import io.choerodon.mybatis.domain.AuditDomain;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.persistence.Table;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.rocketmq.common.message.MessageExt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

@Table(name = "mqMessage")
public class MqMessage extends AuditDomain {
  private static final Logger LOGGER = LoggerFactory.getLogger(MqMessage.class);
  
  private Long eventId;
  
  private Integer tenantFlag;
  
  private String type;
  
  private Integer tlFlag;
  
  private String action;
  
  private String table;
  
  private String keyField;
  
  private String sourceService;
  
  private Date produceTime;
  
  private Long sourceKeyId;
  
  private Long tenantId;
  
  private String status;
  
  private String targetDb;
  
  private String targetTable;
  
  private List<Map<String, Object>> data;
  
  public static List<MqMessage> convertMessageExtToMqMessage(List<MessageExt> messageExtList) {
    List<MqMessage> mqMessageList = new ArrayList<>();
    for (MessageExt messageExt : messageExtList) {
      try {
        mqMessageList.add(JSON.parseObject(messageExt.getBody(), MqMessage.class, new com.alibaba.fastjson.parser.Feature[0]));
      } catch (Exception e) {
        LOGGER.error("CONVERT JSON TO OBJ failed");
        throw new CommonException(e);
      } 
    } 
    return mqMessageList;
  }
  
  public static <T> Comparator<T> compareEventId(Class<T> type) {
    return (o1, o2) -> {
        if (type.isInstance(new MqMessage())) {
          Long obj = ((MqMessage)o1).getEventId();
          Long other = ((MqMessage)o2).getEventId();
          return Integer.parseInt(String.valueOf(obj.longValue() - other.longValue()));
        } 
        return Integer.parseInt(o1.toString()) - Integer.parseInt(o2.toString());
      };
  }
  
  public List<MqMessage> plainMsg() {
    List<MqMessage> mqMessageList = new ArrayList<>();
    if (CollectionUtils.isNotEmpty(this.data))
      this.data.forEach(item -> {
            MqMessage mqMessage = new MqMessage();
            BeanUtils.copyProperties(this, mqMessage);
            mqMessage.setData(Collections.singletonList(item));
            mqMessage.setSourceKeyId(Long.valueOf(Long.parseLong(item.get(this.keyField).toString())));
            mqMessageList.add(mqMessage);
          }); 
    return mqMessageList;
  }
  
  public Long getEventId() {
    return this.eventId;
  }
  
  public void setEventId(Long eventId) {
    this.eventId = eventId;
  }
  
  public Integer getTenantFlag() {
    return this.tenantFlag;
  }
  
  public void setTenantFlag(Integer tenantFlag) {
    this.tenantFlag = tenantFlag;
  }
  
  public String getType() {
    return this.type;
  }
  
  public void setType(String type) {
    this.type = type;
  }
  
  public Integer getTlFlag() {
    return this.tlFlag;
  }
  
  public void setTlFlag(Integer tlFlag) {
    this.tlFlag = tlFlag;
  }
  
  public String getAction() {
    return this.action;
  }
  
  public void setAction(String action) {
    this.action = action;
  }
  
  public String getTable() {
    return this.table;
  }
  
  public void setTable(String table) {
    this.table = table;
  }
  
  public String getKeyField() {
    return this.keyField;
  }
  
  public void setKeyField(String keyField) {
    this.keyField = keyField;
  }
  
  public List<Map<String, Object>> getData() {
    return this.data;
  }
  
  public void setData(List<Map<String, Object>> data) {
    this.data = data;
  }
  
  public String getSourceService() {
    return this.sourceService;
  }
  
  public void setSourceService(String serviceCode) {
    this.sourceService = serviceCode;
  }
  
  public Date getProduceTime() {
    return this.produceTime;
  }
  
  public void setProduceTime(Date produceTime) {
    this.produceTime = produceTime;
  }
  
  public Long getSourceKeyId() {
    return this.sourceKeyId;
  }
  
  public void setSourceKeyId(Long sourceKeyId) {
    this.sourceKeyId = sourceKeyId;
  }
  
  public Long getTenantId() {
    return this.tenantId;
  }
  
  public void setTenantId(Long tenantId) {
    this.tenantId = tenantId;
  }
  
  public String getStatus() {
    return this.status;
  }
  
  public void setStatus(String status) {
    this.status = status;
  }
  
  public String getTargetDb() {
    return this.targetDb;
  }
  
  public void setTargetDb(String targetDb) {
    this.targetDb = targetDb;
  }
  
  public String getTargetTable() {
    return this.targetTable;
  }
  
  public void setTargetTable(String targetTable) {
    this.targetTable = targetTable;
  }
}
